#pragma once

#include <vector>

/**
========================
Contains an entities inventory
TODO- Add items? for now just weapons
========================
*/
template<class T>
class Inventory
{
public:
    Inventory(void) {     
        m_current = 0;
        EmptyBin(); 
    };

    /** Check for an item */
    bool Has(T ent);
    /** Checks for an item by name */
    bool Has(const std::string &s);

    /** Get an item by name */
    T GetItem(const std::string &s);

    /** Retrieve the next item */
    void NextItem();

    /** Retrieve the prev item */
    void PrevItem();

    /** Get the current item */
    T CurrentItem();

    /** Add an item */
    void Add(T item);
    /** Remove an item */
    void Remove(T item);
    /** Remove an item by name */
    void Remove(const std::string &s);

    /** Remove All */
    void EmptyBin();

    /** check if the bin is empty */
    bool IsEmpty() { return m_itemBin.empty(); };

    /** How many item are in this bin */
    size_t AmountOfItems() { return m_itemBin.size(); };

private:
    typedef std::vector<T> type_Bin;
    type_Bin m_itemBin;
    // current item
    int m_current;

public:
    virtual ~Inventory(void);
};

/** Since we released these entities from the EntManager,
 *  we need to add them back
 */
template<class T>
Inventory<T>::~Inventory(void)
{
    EmptyBin();
}

/** Check for an item */
template<class T>
bool Inventory<T>::Has(T ent)
{
    type_Bin::iterator it = m_itemBin.begin();
    for(; it != m_itemBin.end(); it++ )
    {
        if ( *it == ent )
            return true;
    }
    return false;
}
/** Checks for an item by name */
template<class T>
bool Inventory<T>::Has(const std::string &s)
{
    type_Bin::iterator it = m_itemBin.begin();
    for(; it != m_itemBin.end(); it++ )
    {
        if ( *it->GetName() == s )
            return true;
    }
    return false;

}

/** Get an item by name */
template<class T>
T Inventory<T>::GetItem(const std::string &s)
{
    type_Bin::iterator it = m_itemBin.begin();
    for(; it != m_itemBin.end(); it++ )
    {
        if ( *it->GetName() == s )
            return *it;
    }
    return NULL;
}

/** Retrieve the next item */
template<class T>
void Inventory<T>::NextItem()
{
    ++m_current;
    if ( m_current >= AmountOfItems() )
        m_current = AmountOfItems()-1;
}

/** Retrieve the prev item */
template<class T>
void Inventory<T>::PrevItem()
{
    --m_current;
    if ( m_current < 0 )
        m_current = 0;
}

/** Get the current item */
template<class T>
T Inventory<T>::CurrentItem()
{
    return m_itemBin[m_current];
}

/** Remove All */
template<class T>
void Inventory<T>::EmptyBin()
{
    // EntityManager* entMng = EntityManager::GetInstance();
    type_Bin::iterator it = m_itemBin.begin();
    for(; it != m_itemBin.end(); it++ )
    {
        if ( *it ) { // FIXME - appears to be a leak
            // entMng->AddEntity( *it );
            delete *it;
        }
    }
    m_itemBin.clear();
}




/** Remove an item */
template<class T>
void Inventory<T>::Remove(T item)
{
    type_Bin::iterator it = m_itemBin.begin();
    for(; it != m_itemBin.end(); it++ )
    {
        if ( *it == s ) {
            m_itemBin.erase( it );
            return;
        }
    }
}

/** Remove an item by name */
template<class T>
void Inventory<T>::Remove(const std::string &s)
{
    type_Bin::iterator it = m_itemBin.begin();
    for(; it != m_itemBin.end(); it++ )
    {
        if ( *it->GetName() == s ) {
            m_itemBin.erase( it );
            return;
        }
    } 
}

/** Add an item */
template<class T>
void Inventory<T>::Add(T item)
{
    m_itemBin.push_back( item );
}